/*
 * Created on Jan 5, 2005
 *
 * TODO To change the template for this generated file go to
 * Window - Preferences - Java - Code Style - Code Templates
 */
package bmoofxbridge;

import java.io.IOException;
import java.io.OutputStream;
import java.sql.Statement;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.TreeSet;

import org.apache.commons.collections.MultiHashMap;
import org.apache.commons.collections.MultiMap;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlObject;
import org.jaxen.function.TranslateFunction;

import bmoofxbridge.model.Account;
import bmoofxbridge.model.CreditCardAccount;
import bmoofxbridge.model.CreditCardTransaction;
import bmoofxbridge.model.Model;
import bmoofxbridge.model.Transaction;

import com.develop.jawin.COMException;

import net.ofx.types.x2003.x04.AccountEnum;
import net.ofx.types.x2003.x04.AccountInfo;
import net.ofx.types.x2003.x04.AccountInfoResponse;
import net.ofx.types.x2003.x04.AccountInfoTransactionResponse;
import net.ofx.types.x2003.x04.BankAccount;
import net.ofx.types.x2003.x04.BankAccountInfo;
import net.ofx.types.x2003.x04.BankRequestMessageSetV1;
import net.ofx.types.x2003.x04.BankResponseMessageSetV1;
import net.ofx.types.x2003.x04.BankTransactionList;
import net.ofx.types.x2003.x04.CreditCardAccountInfo;
import net.ofx.types.x2003.x04.CreditCardStatementRequest;
import net.ofx.types.x2003.x04.CreditCardStatementResponse;
import net.ofx.types.x2003.x04.CreditCardStatementTransactionRequest;
import net.ofx.types.x2003.x04.CreditCardStatementTransactionResponse;
import net.ofx.types.x2003.x04.CreditcardRequestMessageSetV1;
import net.ofx.types.x2003.x04.CreditcardResponseMessageSetV1;
import net.ofx.types.x2003.x04.Currency;
import net.ofx.types.x2003.x04.CurrencyEnum;
import net.ofx.types.x2003.x04.FinancialInstitution;
import net.ofx.types.x2003.x04.LanguageEnum;
import net.ofx.types.x2003.x04.LedgerBalance;
import net.ofx.types.x2003.x04.OFX;
import net.ofx.types.x2003.x04.OFXDocument;
import net.ofx.types.x2003.x04.SeverityEnum;
import net.ofx.types.x2003.x04.SignonResponse;
import net.ofx.types.x2003.x04.SignonResponseMessageSetV1;
import net.ofx.types.x2003.x04.SignupRequestMessageSetV1;
import net.ofx.types.x2003.x04.SignupResponseMessageSetV1;
import net.ofx.types.x2003.x04.StatementRequest;
import net.ofx.types.x2003.x04.StatementResponse;
import net.ofx.types.x2003.x04.StatementTransaction;
import net.ofx.types.x2003.x04.StatementTransactionRequest;
import net.ofx.types.x2003.x04.StatementTransactionResponse;
import net.ofx.types.x2003.x04.Status;
import net.ofx.types.x2003.x04.TransactionEnum;
import il.co.fibi.bmo.BMOLib._DBMO;

/**
 * @author leonidr
 *
 * TODO To change the template for this generated type comment go to
 * Window - Preferences - Java - Code Style - Code Templates
 */
public class BMOParser {
	public _DBMO bmo;
	
	
	public static final SimpleDateFormat toOFXDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
	public static final SimpleDateFormat fromOFXDateFormat = new SimpleDateFormat("yyyyMMdd");
	public static final SimpleDateFormat fromBMODateFormat = new SimpleDateFormat("dd/MM/yyyy");
	public static Currency ILS = Currency.Factory.newInstance();
	
	{
	    ILS.setCURSYM(CurrencyEnum.ILS);
	}
	
	
	public BMOParser(_DBMO bmo){
		this.bmo = bmo;
	}
	public String getValue(short[] indexes) throws COMException {
		return bmo.ValueC(indexes[0],indexes[1]);
	}
	
	public double getValue(short index) throws COMException {
		return bmo.ValueCD(index);
	}
	
	
	
	public Account getBankAccount() throws COMException {		
		Account bmoAccount = new Account(this);
		return bmoAccount;
	}
	
	public Account[] getBankAccounts() throws COMException {
		List resultList = new ArrayList();
		bmo.Close();
		bmo.Clear();
		bmo.Command("open itrot.dat");
		bmo.Command ("Set Field String 1");
		bmo.Command ("Set Op *");
		bmo.Command ("Set Val *");
		bmo.Command ("Set Sort Ascend");
		bmo.Command ("Build");
		bmo.SetHead();
		bmo.SavePos((short)0);
		
		while (!bmo.IsEndOfList()) {
			resultList.add(getBankAccount());
			bmo.Move(1);
		}
		
		Account[] result = (Account[]) resultList.toArray(new Account[resultList.size()]);
		return result;
		
	}
	
	
	public Transaction getCheckingTransaction() throws COMException {
        Transaction trns = new Transaction(this);
        return trns;
	}
	
	public CreditCardTransaction getCreditCardTransaction() throws COMException {
		CreditCardTransaction trns = new CreditCardTransaction(this);
        return trns;
	}
	
	public CreditCardTransaction[] getCreditCardTransactions() throws COMException {
		List resultList = new ArrayList();
		bmo.Close();
		bmo.Command("open visaold.dat");
		bmo.Command("Set Field String 2");
		bmo.Command("Set Op *");
		bmo.Command("Set Val *");
		bmo.Command("Build");
		bmo.Sort((short)2,(short)3,1);
		bmo.SetHead();
		bmo.SavePos((short)0);
		
		while (!bmo.IsEndOfList()) {
			resultList.add(getCreditCardTransaction());
			bmo.Move(1);
		}
		
		bmo.Close();
		bmo.Command("open visanew.dat");
		bmo.Command("Set Field Date 1");
		bmo.Command("Set Op *");
		bmo.Command("Set Val 00/00/00");
		bmo.Command("Set Sort Ascend");
		bmo.Command("Build");
		bmo.SetHead();
		bmo.SavePos((short)0);
		
		while (!bmo.IsEndOfList()) {
			resultList.add(getCreditCardTransaction());
			bmo.Move(1);
		}
		
		CreditCardTransaction[] result = (CreditCardTransaction[]) resultList.toArray(new CreditCardTransaction[resultList.size()]);
		return result;
		
	}
	

	public Transaction[] getCheckingTransactions() throws COMException {
		List resultList = new ArrayList();
		bmo.Close();
		bmo.Clear();
		bmo.Command("open tnuot.dat");
		bmo.Command("Set Field Date 2");
		bmo.Command("Set Op *");
		bmo.Command("Set Val 0/0/0");
		bmo.Command("Set Sort Ascend");
		bmo.Command ("Build");
		bmo.SetHead();
		bmo.SavePos((short)0);
		
		while (!bmo.IsEndOfList()) {
			resultList.add(getCheckingTransaction());
			bmo.Move(1);
		}
		
		Transaction[] result = (Transaction[]) resultList.toArray(new Transaction[resultList.size()]);
		return result;
		
	}
	
	public static void save(XmlObject[] objects, OutputStream stream) throws IOException {
	    for (int i = 0; i < objects.length; i++) {
            XmlObject object = objects[i];          
            object.save(stream);           
        }
	}
	
	
	public void fillModel(Model model) throws COMException {
//	    Account[] accounts = getBankAccounts();
//	    
//	    for (int i = 0; i < accounts.length; i++) {
//            Account account = accounts[i];
//            model.putAccount(account);
//        }
//	   
	    Transaction[] transactions = getCheckingTransactions();
	    
	    for (int i = 0; i < transactions.length; i++) {
	        Transaction transaction = transactions[i];
            model.putTransaction(transaction);
        }
	    
	    CreditCardTransaction[] creditCardTransactions = getCreditCardTransactions();
	    
	    for (int i = 0; i < creditCardTransactions.length; i++) {
	        Transaction transaction = creditCardTransactions[i];
            model.putTransaction(transaction);
        }	    
	}
	
	
	public OFXDocument getCheckingStatement(Model model) throws COMException {
	    Date now = new Date();
	    OFXDocument result = OFXDocument.Factory.newInstance();
	    
	    OFX ofx = result.addNewOFX();
	    
	    ofx.setSIGNONMSGSRSV1(getSignonResponseMessage(now));
	    BankResponseMessageSetV1 bankmsgsrsv1 = getBankResponseMessage(model, null);
	    ofx.setBANKMSGSRSV1(bankmsgsrsv1);	    
	    return result;
	}

	
	public OFXDocument getFullStatement(Model model, OFXDocument request) throws COMException {
	    Date now = new Date();
	    OFXDocument result = OFXDocument.Factory.newInstance();
	    
	    OFX ofx = result.addNewOFX();

	    if ((request==null) || request.getOFX().isSetSIGNONMSGSRQV1()){
	    	ofx.setSIGNONMSGSRSV1(getSignonResponseMessage(now));
	    }

	    if ((request!=null) && request.getOFX().isSetSIGNUPMSGSRQV1()){
	    	SignupRequestMessageSetV1 SIGNUPMSGSRQV1 = request.getOFX().getSIGNUPMSGSRQV1();
		    ofx.setSIGNUPMSGSRSV1(getSignupResponseMessage(now,model,SIGNUPMSGSRQV1));
    	}

	    if ((request==null) || request.getOFX().isSetBANKMSGSRQV1()){
	    	BankRequestMessageSetV1 BANKMSGSRQV1 = null;
	    	if (request!=null){
	    		BANKMSGSRQV1 = request.getOFX().getBANKMSGSRQV1();
	    	}
		    BankResponseMessageSetV1 bankmsgsrsv1 = getBankResponseMessage(model, BANKMSGSRQV1);
		    ofx.setBANKMSGSRSV1(bankmsgsrsv1);
	    }
	   
	    if ((request!=null) && request.getOFX().isSetCREDITCARDMSGSRQV1()){
	    	CreditcardRequestMessageSetV1 CREDITCARDMSGSRQV1 = request.getOFX().getCREDITCARDMSGSRQV1();
	    	CreditcardResponseMessageSetV1 creditcardmsgsrsv1 = getCreditCardresponseMessage(model,CREDITCARDMSGSRQV1);	    
	    	ofx.setCREDITCARDMSGSRSV1(creditcardmsgsrsv1);
	    }
	    
	    return result;
	}
	
	
	
	/**
	 * @param model
	 * @param bankmsgsrqv1 
	 * @return
	 * @throws COMException
	 */
	private BankResponseMessageSetV1 getBankResponseMessage(Model model, BankRequestMessageSetV1 bankmsgsrqv1) throws COMException {
		BankResponseMessageSetV1 bankmsgsrsv1 = BankResponseMessageSetV1.Factory.newInstance();

		String trnuid = "1";
		
		if (bankmsgsrqv1!=null){
			StatementTransactionRequest[] STMTTRNRQArray = bankmsgsrqv1.getSTMTTRNRQArray();
			
			for (int i = 0; i < STMTTRNRQArray.length; i++) {
				StatementTransactionRequest request = STMTTRNRQArray[i];
				trnuid = request.getTRNUID();
				
			    StatementTransactionResponse stmttrnrs = bankmsgsrsv1.addNewSTMTTRNRS(); 	    
			    stmttrnrs.setTRNUID(trnuid);
			    stmttrnrs.setSTATUS(getStatusOK());
				
				
				StatementRequest STMTRQ = request.getSTMTRQ();
				String accountId = STMTRQ.getBANKACCTFROM().getACCTID();
				Account account = model.getAccount(accountId);

				String reptDate = STMTRQ.getINCTRAN().getDTSTART();
				
				Date requestDate;
				try {
					requestDate = fromOFXDateFormat.parse(reptDate);
				} catch (ParseException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					requestDate= newDate(2006, 1, 1);
				} 
				Collection report = model.getTransactions(account, requestDate);
				
				StatementResponse stmtResp = getStatementResponse(requestDate, account, report);
				stmttrnrs.setSTMTRS(stmtResp);
			}		
		}
		else{
		    Collection checkingAccounts = model.getAccounts(false);
		    ArrayList statementTransactionResponces = new ArrayList();
			for (Iterator iter = checkingAccounts.iterator(); iter.hasNext();) {
				Account account = (Account) iter.next();
				
				MultiMap tranReport = model.getTransactionReportsByAccount(account);
				TreeSet reportDateSet = new TreeSet(tranReport.keySet());
				
				for (Iterator iterator = reportDateSet.iterator(); iterator.hasNext();) {
					Date reportDate = (Date) iterator.next();
					Collection reportTransactions = (Collection) tranReport.get(reportDate);
					StatementTransactionResponse stmttrnrs = getStatementTransactionResponse(reportDate, account, reportTransactions);
					stmttrnrs.setTRNUID(trnuid);
					
					statementTransactionResponces .add(stmttrnrs);				
				}
			}
		    
		    StatementTransactionResponse[] statementTransactionResponcesArray = (StatementTransactionResponse[]) statementTransactionResponces.toArray(new StatementTransactionResponse[statementTransactionResponces.size()]);
		    
		    bankmsgsrsv1.setSTMTTRNRSArray(statementTransactionResponcesArray);
		}
		return bankmsgsrsv1;
	}
	
	
	
	public OFXDocument getCreditCardStatement(Model model) throws COMException {
	    Date now = new Date();
	    OFXDocument result = OFXDocument.Factory.newInstance();
	    
	    OFX ofx = result.addNewOFX();
	    
	    ofx.setSIGNONMSGSRSV1(getSignonResponseMessage(now));
	    
	    CreditcardResponseMessageSetV1 creditcardmsgsrsv1 = getCreditCardresponseMessage(model, null);
	    
	    ofx.setCREDITCARDMSGSRSV1(creditcardmsgsrsv1);	    
	    return result;
	}
	/**
	 * @param model
	 * @param creditcardmsgsrqv1 
	 * @return
	 * @throws COMException
	 */
	private CreditcardResponseMessageSetV1 getCreditCardresponseMessage(Model model, CreditcardRequestMessageSetV1 creditcardmsgsrqv1) throws COMException {
		CreditcardResponseMessageSetV1 creditcardmsgsrsv1 = CreditcardResponseMessageSetV1.Factory.newInstance();
		
		String trnuid = "1";
		
		if (creditcardmsgsrqv1!=null){
			CreditCardStatementTransactionRequest[] CCSTMTTRNRQArray = creditcardmsgsrqv1.getCCSTMTTRNRQArray();
			
			for (int i = 0; i < CCSTMTTRNRQArray.length; i++) {
				CreditCardStatementTransactionRequest request = CCSTMTTRNRQArray[i];
				trnuid = request.getTRNUID();
				
			    CreditCardStatementTransactionResponse stmttrnrs = creditcardmsgsrsv1.addNewCCSTMTTRNRS();    
			    stmttrnrs.setTRNUID(trnuid);
			    stmttrnrs.setSTATUS(getStatusOK());
				
				
				CreditCardStatementRequest CCSTMTRQ = request.getCCSTMTRQ();
				String accountId = CCSTMTRQ.getCCACCTFROM().getACCTID();
				CreditCardAccount account = (CreditCardAccount) model.getAccount(accountId);

				String reptDate = CCSTMTRQ.getINCTRAN().getDTSTART();
				
				Date requestDate;
				try {
					requestDate = fromOFXDateFormat.parse(reptDate);
				} catch (ParseException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					requestDate= newDate(2006, 1, 1);
				} 
				
				Collection report = model.getTransactions(account, requestDate);
				
				if (!report.isEmpty()){
					CreditCardStatementResponse stmtResp = getCreditCardStatementResponse(requestDate, account, report);
					stmttrnrs.setCCSTMTRS(stmtResp);
				}
				else{
					stmttrnrs.setSTATUS(getStatusFAIL());
				}
			}		
		}
		else{
		    ArrayList statementTransactionResponces = new ArrayList();
		    
		    Collection creditCardAccounts = model.getAccounts(true);
		    for (Iterator iter = creditCardAccounts.iterator(); iter.hasNext();) {
				CreditCardAccount account = (CreditCardAccount) iter.next();
				MultiMap tranReport = model.getTransactionReportsByAccount(account);
				TreeSet reportDateSet = new TreeSet(tranReport.keySet());
				
				for (Iterator iterator = reportDateSet.iterator(); iterator.hasNext();) {
					Date reportDate = (Date) iterator.next();
					Collection reportTransactions = (Collection) tranReport.get(reportDate);
					CreditCardStatementTransactionResponse cctrnrs = getCreditCardTransactionResponse(reportDate, account, reportTransactions);
					
					statementTransactionResponces.add(cctrnrs);				
				}
			}
		    
		    CreditCardStatementTransactionResponse[] ccTransactionResponcesArray = (CreditCardStatementTransactionResponse[]) statementTransactionResponces.toArray(new CreditCardStatementTransactionResponse[statementTransactionResponces.size()]);	    
		    creditcardmsgsrsv1.setCCSTMTTRNRSArray(ccTransactionResponcesArray);
		}
		return creditcardmsgsrsv1;
	}
	/**
	 * @param date
	 * @param acct
	 * @param transactions
	 * @return
	 * @throws COMException
	 */
	private StatementTransactionResponse getStatementTransactionResponse(Date date, Account acct, Collection transactions) throws COMException {
		Iterator trnsIter = transactions.iterator();        
	    Date startDate = null;
	    List trnsList = new LinkedList();
        int i;
        Iterator iter ;
        Transaction lastTrans = null;
        for (iter = trnsIter, i=0; iter.hasNext(); i++) {
            lastTrans = (Transaction) iter.next();
            StatementTransaction stmtTrans = lastTrans.getCheckingTransaction();
            if (i==0) {
                startDate = lastTrans.getDate(); 
            }                    
            trnsList.add(stmtTrans);
        }
        
        StatementTransaction[] stmtTransactions = (StatementTransaction[]) trnsList.toArray(new StatementTransaction[trnsList.size()]);        
	    StatementTransactionResponse stmttrnrs = StatementTransactionResponse.Factory.newInstance(); 	    
	    stmttrnrs.setTRNUID("1");
	    stmttrnrs.setSTATUS(getStatusOK());
	    {
	        StatementResponse stmtrs = stmttrnrs.addNewSTMTRS();
	        stmtrs.setCURDEF(CurrencyEnum.ILS);
	        stmtrs.setBANKACCTFROM(acct.getBankAccount());
	        {
	            BankTransactionList banktranlist = stmtrs.addNewBANKTRANLIST();
	            banktranlist.setSTMTTRNArray(stmtTransactions);
	            
	            banktranlist.setDTSTART(toOFXDateFormat.format(startDate));
	            banktranlist.setDTEND(toOFXDateFormat.format(date));
	        }
	        {
	            LedgerBalance ledgerbal = stmtrs.addNewLEDGERBAL();
	            ledgerbal.setDTASOF(toOFXDateFormat.format(date));
	            ledgerbal.setBALAMT(String.valueOf(lastTrans.getBalance()));
	        }
	    }
		return stmttrnrs;
	}
	
	public StatementResponse getStatementResponse(Date date, Account acct, Collection transactions) throws COMException{
		Iterator trnsIter = transactions.iterator();        
	    Date startDate = newDate(1970,1,1);
	    List trnsList = new LinkedList();
        int i;
        Iterator iter ;
        Transaction lastTrans = null;
        for (iter = trnsIter, i=0; iter.hasNext(); i++) {
            lastTrans = (Transaction) iter.next();
            StatementTransaction stmtTrans = lastTrans.getCheckingTransaction();
            if (i==0) {
                startDate = lastTrans.getDate(); 
            }                    
            trnsList.add(stmtTrans);
        }
        
        StatementTransaction[] stmtTransactions = (StatementTransaction[]) trnsList.toArray(new StatementTransaction[trnsList.size()]);        
        
        StatementResponse stmtrs = StatementResponse.Factory.newInstance(); 
        stmtrs.setCURDEF(CurrencyEnum.ILS);
        stmtrs.setBANKACCTFROM(acct.getBankAccount());
        {
            BankTransactionList banktranlist = stmtrs.addNewBANKTRANLIST();
            banktranlist.setSTMTTRNArray(stmtTransactions);
            
            banktranlist.setDTSTART(toOFXDateFormat.format(startDate));
            banktranlist.setDTEND(toOFXDateFormat.format(date));
        }
        {
            LedgerBalance ledgerbal = stmtrs.addNewLEDGERBAL();
            ledgerbal.setDTASOF(toOFXDateFormat.format(lastTrans.getStatementDate()));
            ledgerbal.setBALAMT(String.valueOf(lastTrans.getBalance()));
        }
        
        return stmtrs;
	}
	
	/**
	 * @param date
	 * @param acct
	 * @param transactions
	 * @return
	 * @throws COMException
	 */
	private CreditCardStatementTransactionResponse getCreditCardTransactionResponse(Date date, CreditCardAccount acct, Collection transactions) throws COMException {
		Iterator trnsIter = transactions.iterator();        
	    Date startDate = newDate(1970,1,1);
	    List trnsList = new LinkedList();
        int i;
        Iterator iter ;
        CreditCardTransaction lastTrans = null;
        for (iter = trnsIter, i=0; iter.hasNext(); i++) {
            lastTrans = (CreditCardTransaction) iter.next();
            StatementTransaction stmtTrans = lastTrans.getCreditCardTransaction();
            if (i==0) {
                startDate = lastTrans.getDate(); 
            }                    
            trnsList.add(stmtTrans);
        }
        
        StatementTransaction[] stmtTransactions = (StatementTransaction[]) trnsList.toArray(new StatementTransaction[trnsList.size()]);        
        CreditCardStatementTransactionResponse stmttrnrs = CreditCardStatementTransactionResponse.Factory.newInstance(); 	    
	    stmttrnrs.setTRNUID("1");
	    stmttrnrs.setSTATUS(getStatusOK());
	    {
	        CreditCardStatementResponse stmtrs = stmttrnrs.addNewCCSTMTRS();
	        stmtrs.setCURDEF(CurrencyEnum.ILS);
	        stmtrs.setCCACCTFROM(acct.getCreditCardAccount());	        
	        {
	            BankTransactionList banktranlist = stmtrs.addNewBANKTRANLIST();
	            banktranlist.setSTMTTRNArray(stmtTransactions);
	            
	            banktranlist.setDTSTART(toOFXDateFormat.format(startDate));
	            banktranlist.setDTEND(toOFXDateFormat.format(date));
	        }
	        {
	            LedgerBalance ledgerbal = stmtrs.addNewLEDGERBAL();
	            ledgerbal.setDTASOF(toOFXDateFormat.format(date));
	            ledgerbal.setBALAMT(String.valueOf(lastTrans.getBalance()));
	        }
	    }
		return stmttrnrs;
	}
	
	
	public CreditCardStatementResponse getCreditCardStatementResponse(Date date, CreditCardAccount acct, Collection transactions) throws COMException{
		CreditCardStatementResponse stmtrs = CreditCardStatementResponse.Factory.newInstance();
		
		Iterator trnsIter = transactions.iterator();        
	    Date startDate = newDate(1970,1,1);
	    List trnsList = new LinkedList();
        int i;
        Iterator iter ;
        CreditCardTransaction lastTrans = null;
        for (iter = trnsIter, i=0; iter.hasNext(); i++) {
            lastTrans = (CreditCardTransaction) iter.next();
            StatementTransaction stmtTrans = lastTrans.getCreditCardTransaction();
            if (i==0) {
                startDate = lastTrans.getDate(); 
            }                    
            trnsList.add(stmtTrans);
        }
        
        StatementTransaction[] stmtTransactions = (StatementTransaction[]) trnsList.toArray(new StatementTransaction[trnsList.size()]);        
        stmtrs.setCURDEF(CurrencyEnum.ILS);
        stmtrs.setCCACCTFROM(acct.getCreditCardAccount());	        
        {
            BankTransactionList banktranlist = stmtrs.addNewBANKTRANLIST();
            banktranlist.setSTMTTRNArray(stmtTransactions);
            
            banktranlist.setDTSTART(toOFXDateFormat.format(startDate));
            banktranlist.setDTEND(toOFXDateFormat.format(date));
        }
        {
            LedgerBalance ledgerbal = stmtrs.addNewLEDGERBAL();
            ledgerbal.setDTASOF(toOFXDateFormat.format(date));
            ledgerbal.setBALAMT(String.valueOf(lastTrans.getBalance()));
        }

		
		return stmtrs;
	}
	
	
	
	/**
	 * @param now
	 * @return
	 */
	private SignonResponseMessageSetV1 getSignonResponseMessage(Date now) {
		SignonResponseMessageSetV1 signonmsgsrsv1 = SignonResponseMessageSetV1.Factory.newInstance(); 	    	
	    {
            SignonResponse sonrs = signonmsgsrsv1.addNewSONRS();
        
            Status status = getStatusOK();            
        	sonrs.setSTATUS(status);
        
            sonrs.setDTSERVER(toOFXDateFormat.format(now));
            sonrs.setLANGUAGE(LanguageEnum.ENG);
            {
                FinancialInstitution fi = sonrs.addNewFI();
                fi.setFID("POALIM");
                fi.setORG("BANKHAPOALIM");
            }
        }
		return signonmsgsrsv1;
	}
	
	private SignupResponseMessageSetV1 getSignupResponseMessage(Date now, Model model, SignupRequestMessageSetV1 signupmsgsrqv1) {
		
		SignupResponseMessageSetV1 signupmsgsrsv1 = SignupResponseMessageSetV1.Factory.newInstance(); 	    	
	    {
	    	AccountInfoTransactionResponse actInfoTrnResp = signupmsgsrsv1.addNewACCTINFOTRNRS();
	    	actInfoTrnResp.setSTATUS(getStatusOK());
	    	
	    	String trnuid = signupmsgsrqv1.getACCTINFOTRNRQArray(0).getTRNUID();
	    	actInfoTrnResp.setTRNUID(trnuid);
	    	
		    Collection allAccounts = model.getAccounts(false);
		    Collection creditAccounts = model.getAccounts(true);
		    allAccounts.addAll(creditAccounts);

			AccountInfoResponse acctInfoRs = actInfoTrnResp.addNewACCTINFORS();
			acctInfoRs.setDTACCTUP(toOFXDateFormat.format(now));

		    for (Iterator iter = allAccounts.iterator(); iter.hasNext();) {
				Account account = (Account) iter.next(); 
	    	
		    	AccountInfo acctInfo = acctInfoRs.addNewACCTINFO();
		    	acctInfo.setDESC(account.getAccountID());
		    	acctInfo.setPHONE("555-555-555");
		    	
		    	if (account instanceof CreditCardAccount){
		    		CreditCardAccountInfo ccAcctInfo = acctInfo.addNewCCACCTINFO();
		    		ccAcctInfo.setSVCSTATUS(net.ofx.types.x2003.x04.ServiceStatusEnum.ACTIVE);
		    		ccAcctInfo.setSUPTXDL(net.ofx.types.x2003.x04.BooleanType.Y);
		    		ccAcctInfo.setXFERDEST(net.ofx.types.x2003.x04.BooleanType.N);
		    		ccAcctInfo.setXFERSRC(net.ofx.types.x2003.x04.BooleanType.N);
		    		ccAcctInfo.setCCACCTFROM(((CreditCardAccount)account).getCreditCardAccount());
		    	}
		    	else{
			    	BankAccountInfo bankAcctInfo = acctInfo.addNewBANKACCTINFO();
			    	bankAcctInfo.setSVCSTATUS(net.ofx.types.x2003.x04.ServiceStatusEnum.ACTIVE);
			    	bankAcctInfo.setSUPTXDL(net.ofx.types.x2003.x04.BooleanType.Y);
			    	bankAcctInfo.setXFERDEST(net.ofx.types.x2003.x04.BooleanType.N);
			    	bankAcctInfo.setXFERSRC(net.ofx.types.x2003.x04.BooleanType.N);
			    	bankAcctInfo.setBANKACCTFROM(account.getBankAccount());
		    	}
		    }
        }
		return signupmsgsrsv1;
	}
	/**
	 * @return
	 */
	private Status getStatusOK() {
		Status status = Status.Factory.newInstance(); 
		status.setCODE("0");
		status.setSEVERITY(SeverityEnum.INFO);
		return status;
	}
	
	private Status getStatusFAIL() {
		Status status = Status.Factory.newInstance(); 
		status.setCODE("1000");
		status.setSEVERITY(SeverityEnum.WARN);
		return status;
	}
	
	public Date newDate(int year, int month, int day){
		Calendar cldr = Calendar.getInstance();
		cldr.set(year, month, day);
		Date date = cldr.getTime();
		return date;
	}

}
